package com.easy.frame.servers.sys.controller.menu;

import cn.hutool.core.util.ObjectUtil;
import com.easy.frame.base.api.pojo.PageDTO;
import com.easy.frame.base.api.pojo.PageVO;
import com.easy.frame.base.basic.ServiceResponse;
import com.easy.frame.base.basic.pojo.vo.BaseTreeVO;
import com.easy.frame.base.service.base.BaseController;
import com.easy.frame.base.service.tree.TreeHandler;
import com.easy.frame.servers.sys.client.SysMenuClient;
import com.easy.frame.servers.sys.dto.SysMenuPageDTO;
import com.easy.frame.servers.sys.entity.SysMenu;
import com.easy.frame.servers.sys.entity.SysSetting;
import com.easy.frame.servers.sys.entity.SysTenantMenu;
import com.easy.frame.servers.sys.service.menu.SysMenuService;
import com.easy.frame.servers.sys.vo.SysMenuPageVO;
import com.easy.frame.servers.sys.vo.SysMenuTreeVO;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 菜单表相关接口类
 * *
 * * @author tp
 * * @date 2020/12/21 15:18
 */
@Slf4j
@Api(tags = "菜单/sys-menu")
@RestController
@RequestMapping("/sys-menu")
public class SysMenuController extends BaseController implements SysMenuClient {

    @Autowired
    SysMenuService service;

    @ApiOperation("分页")
    @PostMapping("/page")
    public ServiceResponse<PageVO<SysMenuPageVO>> page(@RequestBody PageDTO<SysMenuPageDTO> param) {
        PageVO<SysMenuPageVO> result = service.selectForPage(param);
        return success(result);
    }

    @ApiOperation("查询-根据id")
    @GetMapping("/by/id")
    public ServiceResponse<SysMenu> getById(@ApiParam(value = "主键id", required = true)
                                            @NotNull @RequestParam Long id) {
        return success(service.selectById(id));
    }

    @Override
    @ApiOperation("查询-查找租户菜单集合（根据租户id）")
    @GetMapping("/by/tenantId")
    public ServiceResponse<List<SysTenantMenu>> getSysMenuById(@ApiParam(value = "租户id", required = true)
                                                               @NotNull @RequestParam Long tenantId) {
        return success(service.getSysMenuById(tenantId));
    }

    @ApiOperation("保存")
    @PostMapping
    public ServiceResponse<SysMenu> save(@RequestBody SysMenu entity) {
        service.addTree(entity);
        return success(entity);
    }

    @ApiOperation("修改-根据id")
    @PutMapping
    public ServiceResponse<SysMenu> update(@RequestBody SysMenu entity) {
        service.updateEntityById(entity);
        return success(entity);
    }

    @ApiOperation("删除-根据id")
    @DeleteMapping("/by/id")
    public ServiceResponse<?> deleteById(@RequestParam @NotNull Long id) {
        service.updateDeleted(id);
        return success();
    }

    @ApiOperation("添加租户菜单权限列表")
    @PostMapping("/tenant")
    public ServiceResponse<?> addTenant(@ApiParam("租户id")
                                        @RequestBody SysTenantMenu tenantMenu) {
        service.addTenant(tenantMenu);
        return success();
    }

    @ApiOperation("查询获取所有菜单menuList权限列表")
    @PostMapping("/list")
    public ServiceResponse<List<SysMenu>> menuList(@RequestParam Integer sysMenu) {
        List<SysMenu> sysMenus = service.menuSysList(sysMenu);
        return success(sysMenus);
    }

    @ApiOperation("获取菜单menuList权限树Tree列表")
    @PostMapping("/list/tree")
    public ServiceResponse<BaseTreeVO> menuTreeList(@RequestParam Integer sysMenu) {
        List<SysMenu> sysMenus = service.menuSysList(sysMenu);
        BaseTreeVO tree = TreeHandler.of(SysMenuTreeVO.class).getTree(sysMenus);
        return success(tree);
    }

    @ApiOperation(value = "查询租户菜单权限列表", notes = "返回系统所有有效菜单列表，并标记已有权限")
    @PostMapping("/list/tenant")
    public ServiceResponse<? extends BaseTreeVO> listTenant(@ApiParam("租户id")
                                                            @RequestParam Long tenantId) {
        return success(service.listTenant(tenantId));
    }

    @ApiOperation(value = "查询角色菜单权限列表", notes = "返回系统所有有效菜单列表，并标记已有权限")
    @PostMapping("/list/role")
    @CrossOrigin(origins = "*", maxAge = 3600)
    public ServiceResponse<? extends BaseTreeVO> listRole(@ApiParam("角色id")
                                                          @RequestParam Long roleId) {
        return success(service.listRole(roleId));
    }

    @ApiOperation(value = "查询员工菜单权限列表", notes = "返回系统所有有效菜单列表，并标记已有权限")
    @PostMapping("/list/staff")
    public ServiceResponse<? extends BaseTreeVO> listStaff(@ApiParam("员工id")
                                                           @RequestParam Long staffId) {
        return success(service.listStaff(staffId));
    }

    @ApiOperation("授权租户")
    @PostMapping("/auth/tenant")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "租户id", name = "tenantId"),
            @ApiImplicitParam(value = "菜单id：操作集合 map", name = "menuId2OptionListMap")
    })
    public ServiceResponse<?> authTenant(@RequestParam Long tenantId,
                                         @RequestBody Map<Long, List<String>> menuId2OptionListMap) {
        if (ObjectUtil.isEmpty(menuId2OptionListMap)) {
            return fail("菜单权限不能为空");
        }
        service.authTenant(tenantId, menuId2OptionListMap);
        return success();
    }

    @ApiOperation("授权角色")
    @PostMapping("/auth/role")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "角色id", name = "roleId"),
            @ApiImplicitParam(value = "菜单id：操作集合 map", name = "menuId2OptionListMap"),
            @ApiImplicitParam(value = "是否同步修改角色下的用户菜单", name = "isSyncChangeStaff")
    })
    public ServiceResponse<?> authRole(@RequestParam Long roleId,
                                       @RequestBody Map<Long, List<String>> menuId2OptionListMap,
                                       @RequestParam boolean isSyncChangeStaff) {
        if (ObjectUtil.isEmpty(menuId2OptionListMap)) {
            return fail("菜单权限不能为空");
        }
        service.authRole(roleId, menuId2OptionListMap, isSyncChangeStaff);
        return success();
    }

    @ApiOperation("授权员工")
    @PostMapping("/auth/staff")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "员工id", name = "staffId"),
            @ApiImplicitParam(value = "菜单id：操作集合 map", name = "menuId2OptionListMap")
    })
    public ServiceResponse<?> authStaff(@RequestParam Long staffId,
                                        @RequestBody Map<Long, List<String>> menuId2OptionListMap) {
        if (ObjectUtil.isEmpty(menuId2OptionListMap)) {
            return fail("菜单权限不能为空");
        }
        service.authStaff(staffId, menuId2OptionListMap);
        return success();
    }

    /**
     * ----------------自定义菜单部分，从sys_setting表中获取数据------------------------
     */
    // TODO SysSetting的接口和逻辑写到SysSettingController中去
    @ApiOperation("根据id查询")
    @GetMapping("/menu/head")
    public ServiceResponse<Map<String, SysSetting>> selectMenuHead(@ApiParam("主键id") @RequestParam Long id) {
        List<SysSetting> menuList = service.selectMenuHead();
        Map<String, SysSetting> settingMap =
                menuList.stream().collect(Collectors.toMap(SysSetting::getCode, Function.identity()));
        return success(settingMap);
    }

    @ApiOperation("保存自定义菜单")
    @PostMapping("/menu/setting")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "修改导航条样式1(罗列式)3(横向抽屉)2(纵向抽屉)", name = "navValue", required = true),
            @ApiImplicitParam(value = "setting表css", name = "cssValue"),
            @ApiImplicitParam(value = "第三方菜单地址", name = "menuAddress")
    })
    public ServiceResponse<?> saveSetting(@RequestParam("navValue") String navValue,
                                          @RequestParam(value = "cssValue", required = false) String cssValue,
                                          @RequestParam(value = "menuAddress", required = false) String menuAddress) {
        service.saveSetting(navValue, cssValue, menuAddress);
        return success();
    }

    @ApiOperation("移动节点")
    @GetMapping("/move-node")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "需要移动的节点id", name = "movedNodeId"),
            @ApiImplicitParam(value = "新的父节点的id", name = "newParentNodeId")
    })
    public ServiceResponse<?> moveNode(@RequestParam Integer movedNodeId,
                                       @RequestParam(required = false) Integer newParentNodeId) {
        System.out.println("movedNodeId = " + movedNodeId);
        service.moveNode(movedNodeId, newParentNodeId);
        return success();
    }

    @ApiOperation("删除节点")
    @DeleteMapping("/by-id")
    public ServiceResponse<?> deleteNode(@RequestParam Long id) {
        service.deleteNode(id);
        return success();
    }

    @Override
    @ApiOperation("权限同步员工权限对外接口")
    @GetMapping("/async-staff")
    public void asyncStaff(@RequestParam Long roleId,
                           @RequestParam Map<String, List<String>> menuId2OptionListMap,
                           @RequestParam Boolean isSyncChangeStaff,
                           @RequestParam Long currentUserId) {
        Map<Long, List<String>> collect = menuId2OptionListMap.entrySet().stream()
                .collect(Collectors.toMap(e -> Long.valueOf(e.getKey()), Map.Entry::getValue));
        service.authRoleAsync(Collections.singletonList(roleId), collect, isSyncChangeStaff, currentUserId);
    }

}
